package com.cuijq.ms.Iteratordesign.v2;

/**
 * @author by CuiJQ
 * @Classname SnapshotArrayIterator
 * @Description SnapshotArrayIterator Description
 * @Date 2021/5/29 16:47
 * <p>
 * 都要拷贝一份数据到快照中，会增加内存的消耗。如果一个容器同时有多个迭代器在遍历元素， 就会导致数据在内存中重复存储多份。 不过，庆幸的是，Java 中的拷贝属于浅拷贝，也就是说，容器中的对象并非真的拷贝了多份
 */
public class SnapshotArrayIterator<E> implements Iterator<E> {

  private long snapshotTimestamp;
  private int cursorInAll;
  // 在整个容器中的下标，而非快照中的下标
  private int leftCount;
  // 快照中还有几个元素未被遍历
  private ArrayList<E> arrayList;

  public SnapshotArrayIterator(ArrayList arrayList) {
    this.snapshotTimestamp = System.currentTimeMillis();
    this.cursorInAll = 0;
    this.leftCount = arrayList.actualSize();
    this.arrayList = arrayList;
    justNext(); // 先跳到这个迭代器快照的第一个元素
  }

  @Override
  public boolean hasNext() {
    return this.leftCount
        >= 0; // 注意是>=, 而非>
  }

  @Override
  public E next() {
    E currentItem = (E) arrayList.get(cursorInAll);
    justNext();
    return currentItem;
  }

  @Override
  public E currentItem() {
    return null;
  }

  private void justNext() {
    while (cursorInAll < arrayList.totalSize()) {
      long addTimestamp = arrayList.getAddTimestamp(cursorInAll);
      long delTimestamp = arrayList.getDelTimestamp(cursorInAll);
      if (snapshotTimestamp > addTimestamp && snapshotTimestamp < delTimestamp) {
        leftCount--;
        break;
      }
      cursorInAll++;
    }
  }
}

